<?php

class PlayerRegistry
{
	private static $sInstance;
	
	private $oRecords;
	private $oAllLoaded;
	
	private function __construct() 
	{ 
		$this->oRecords = array();
		$this->oAllLoaded = false;
	}
	
	private function __clone() {}
	
	public static function &i()
	{
		if (is_null(self::$sInstance) || !is_object(self::$sInstance))
			self::$sInstance = new PlayerRegistry();
		
		return self::$sInstance;
	}
	
	public function byName($name)
	{
		foreach ($this->oRecords as $record)
		{
			if ($record["obj"]->name() == $name) return $record["obj"];
		}
		
		if (!$this->oAllLoaded)
			$player = PlayerMapper::byName($name);
		
		if (is_null($player)) return null;
		
		$this->oRecords[$player->id()] = array("obj" => $player, "state" => ObjectState::NORMAL);
		return $player;
	}
	
	public function byMail($mail)
	{
		foreach ($this->oRecords as $record)
		{
			if ($record["obj"]->mail() == $mail) return $record["obj"];
		}
		
		if (!$this->oAllLoaded)
			$player = PlayerMapper::byMail($mail);
		if (is_null($player)) return null;
		
		$this->oRecords[$player->id()] = array("obj" => $player, "state" => ObjectState::NORMAL);
		return $player;
	}
	
	public function add(PlayerObject $player)
	{
		if (!PlayerMapper::insert($player))
			return false;
		
		$this->oRecords[$player->id()] = array("obj" => $player, "state" => ObjectState::NORMAL);
		
		return true;
	}
	
	public function byId($id)
	{
		if (array_key_exists($id, $this->oRecords)) return $this->oRecords[$id]["obj"]; 
		
		if (!$this->oAllLoaded)
			$player = PlayerMapper::byId($id);
		
		if (is_null($player)) return null;
	
		$this->oRecords[$id] = array("obj" => $player, "state" => ObjectState::NORMAL);
		return $player;
	}
	
	public function playerList()
	{
		if (!$this->oAllLoaded)
		{
			$idList = PlayerMapper::playersId();
			foreach ($idList as $id)
			{
				if (!array_key_exists($id, $this->oRecords))
					$this->oRecords[$id] = array("obj" => PlayerMapper::byId($id), "state" => ObjectState::NORMAL);
			}
			
			$this->oAllLoaded = true;
		}
		$objects = array();
		foreach ($this->oRecords as $id => $record)
		{
			if ($record["state"] == ObjectState::NORMAL)
				$objects[$id] = $record["obj"];
		}
		return $objects;
	}
	
	public function removeById($id)
	{
		$player = $this->byId($id);
		if (is_null($player)) return;
		
		$this->oRecords[$player->id()] = array("obj" => $player, "state" => ObjectState::REMOVED);
	}
	
	/** Сохраняет все модифицированные объекты */
	public function flush()
	{
	foreach ($this->oRecords as $record)
		{
			$obj = $record["obj"];
			if ($record["state"] == ObjectState::REMOVED)
				PlayerMapper::delete($obj->id());
			else if ($obj->isModified())
				PlayerMapper::update($obj);
		}
	}
}

?>